package org.bravof.differ.service.support;

import lombok.extern.log4j.Log4j;
import org.bravof.differ.dao.DetailDAO;
import org.bravof.differ.entity.DetailPO;
import org.bravof.differ.util.CommonConst;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 连接工具
 */
@Log4j
@Service
public class ConnectionService {
    @Value("${spring.datasource.driver-class-name}")
    private String DRIVER_CLASS_NAME;

    @Resource
    private DetailDAO detailDAO;

    /**
     * 数据库ID为key，数据库连接为value
     */
    private final Map<String, Connection> connectionMap = new ConcurrentHashMap<>();

    /**
     * 根据配置的ID，获取数据库连接实例
     * @param id
     * @return
     */
    public Connection fetchConnection(String id) {
        Connection connection = connectionMap.get(id);
        if (null != connection) {
            // 测试连接有效性
            try {
                if (!connection.isValid(3000)) {
                    connection.close();
                    connectionMap.put(id, _buildConnection(id));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return connection;
        } else {
            connectionMap.put(id, _buildConnection(id));
            return connectionMap.get(id);
        }
    }

    /**
     * 构建数据库连接实例
     * @param id
     * @return
     */
    private Connection _buildConnection(String id) {
        DetailPO detail = detailDAO.findDetailById(id);
        if (null == detail) {
            log.warn("数据库配置ID-> " + id + " 未配置");
            return null;
        }

        Connection conn = null;
        try {
            Class.forName(DRIVER_CLASS_NAME);
            conn = DriverManager.getConnection(CommonConst.URL_PREFIX + detail.getHost() + CommonConst.SYMBOL_COLON + detail.getPort() + CommonConst.SYMBOL_SLANTING_BAR + detail.getSchemaName(),
                    detail.getUserName(), detail.getPassword());
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}
